//  We place all of the member function implementations in this file for class Lap

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include "Lap.h"
using namespace std;



// Constructor.  Argument is the lap number
Lap::Lap(int num)
{
   lap_num = num;

   read_file();
} // Basic constructor.  Set the lap number and call read_file to read in the datafile



// Destructor
Lap::~Lap()
{
  int i; 

  for (i = 0; i < num_data_vars; i++)
    delete[] lap_data[i];  // delete frees up memory that we allocated with 'new' 
//   ('new' is used in the read_file() function below) 
}
   


//  This is the function used to read lap files into a big 2d array.
void Lap::read_file()
{
   ostringstream fname;  // output string stream - used to write a string
   string filename, line;  
   ifstream inputFile;  // input file stream - used to read a file
   int numlines, i, j;

//  The first thing we need to do is construct the proper filename, e.g. 'lap1' for lap 1.
//   fname is a output string stream, we can write to it just as we would to std::cout
   fname << "lap" << lap_num;
//  The string stream has a member function 'str' which converts the contents 
//   into an ordinary c++ string
   filename = fname.str();

//  Now we're going to open the file.  string has a member function 'c_str' which allows 
//   the ifstream member function 'open' to use it (provides a pointer-based string)
   inputFile.open(filename.c_str(), ios::in);

//  We're going to count the number of lines in the inputFile.  It seems goofy to start with 
//   -1 but it works. 
   numlines = -1; 
   while ( inputFile.good() )    // as long as the input file hasn't reached the end...
   {
      getline(inputFile, line);  // grab the line (only done to advance our position, not stored)
      numlines++;                // increase the count of the number of lines
   }

//  You can delete this output, it's just here for testing.
   cout << "Number of lines is: " << numlines << endl;


//  Now that we know the number of lines, we need to allocate the other dimension of our 2d array
//  After we do this, we can access an element of lapdata[i][j]
   for (i = 0; i < num_data_vars; i++)
      lap_data[i] = new double [numlines]; // 'new' allocates memory and returns a pointer to it

//  Reset the inputFile to the beginning of the file, we're going to read the actual data now
   inputFile.clear();
   inputFile.seekg(0, ios::beg);

   DATAlines = numlines;

//  Nested for loop to read in both dimensions of the 2d data array
   for (j = 0; j < numlines; j++)
   {
      for (i = 0; i < num_data_vars; i++)
      {
//       In this case, getline only reads until it encounters a comma 
//        (comma set as the delimiter)
         getline(inputFile, line, ','); 
//        Convert string variable line into an input string stream (like cin), 
//         stream it to lap_data[i][j] 
         istringstream( line ) >> lap_data[i][j];
      }
   }
//return numlines;
//  Print out a sample data point to be sure things are going ok
//   (just for testing, you can delete this)
//  cout << "vel_mph[111] = " << lap_data[VEL_MPH][111] << endl;

//  Close the input file
   inputFile.close();

} 

int Lap::LapN()
{
	return lap_num;
}

double Lap::LapTime()
{
	double small, large;

	large = lap_data[ELAPSED_TIME][DATAlines-1];
	small = lap_data[ELAPSED_TIME][0];
	//cout << "Grabber time" << DATAlines << " " << large << " " << small << endl;

	return (large-small);
}

double Lap::AVGTime()
{
	double sum = 0;
	for(int i =0; i < DATAlines; i++)
		sum += lap_data[VEL_MPH][i];

	return(sum/DATAlines);
}

double Lap::AVGAccel()
{
	double sum = 0;
	for(int i =0; i < DATAlines; i++)
		sum += lap_data[ACCEL_CALC][i];
	
	return((sum/DATAlines)*100);
}

double Lap::MAXspd()
{
	double Max = 0;
	for(int i =0; i < DATAlines; i++)
	{
		if(lap_data[VEL_MPH][i] > Max)
		Max = lap_data[VEL_MPH][i];
	}
	return Max;
}

double Lap::MINspd()
{
	double Min = 150;
	for(int i =0; i < DATAlines; i++)
	{
		if(lap_data[VEL_MPH][i] < Min)
		Min = lap_data[VEL_MPH][i];
	}
	return Min;
}

double Lap::TURNSPD(double &Turnexit)
{
	bool B = true;
	double Turnen;

	for(int i = 0; i < DATAlines; i++)
	{
		if(lap_data[LAT_DEGREES][i] > 34.1475 && lap_data[LON_DEGREES][i] > - 83.81041 && B)
		{
			Turnen = lap_data[VEL_MPH][i];
			B = false;
		}
		if(lap_data[LAT_DEGREES][i] < 34.1475 || lap_data[LON_DEGREES][i] < - 83.81041 && !B)
		{
			Turnexit = lap_data[VEL_MPH][i-1];
			break;
		}
	}
	return Turnen;
}

void Lap::OUTACCEL(int lapnum)
{

	ostringstream fname;  // output string stream - used to write a string
	ofstream outputfile;
	string filename;

	fname << "lap" << lap_num <<"accel.txt";
    filename = fname.str();
	outputfile.open (filename);
	outputfile.clear();
    //outputfile.seekg(0, ios::beg);

  for(int x = 0; x < DATAlines - 1; x++)
	  outputfile << ((lap_data[VEL_MPH][x+1] - lap_data[VEL_MPH][x])/(lap_data[ELAPSED_TIME][x+1] - lap_data[ELAPSED_TIME][x]))
	  << ", " << lap_data[LAT_FEET][x] << ", " << lap_data[LON_FEET][x];

   //  Close the output file
   outputfile.close();
}